package cn.jdemo.unsafe.offset;

import sun.misc.Unsafe;

/**
 *
 * 基于偏移量修改某个字段值
 * @see Unsafe#putInt(long, int) 
 * @see Unsafe#putInt(Object, long, int)
 *  示例： theUnasfe.putInt( A.class, valOffset1, 2);
 *  示例： theUnasfe.putInt(a, valOffset2, 4);
 * @see Unsafe#putIntVolatile(Object, long, int)
 *
 * @see Unsafe#putBoolean(Object, long offset, boolean) 基于offset修改(静态/非静态)变量值
 * @see Unsafe#putLong(Object, long, long)
 * @see Unsafe#putObject(Object, long, Object)
 * @see Unsafe#putDouble(Object, long, double)
 * @see Unsafe#putFloat(Object, long, float)
 * @see Unsafe#putChar(Object, long, char)
 * @see Unsafe#putByte(Object, long, byte)
 *
 * @date 2021/1/15
 */
public class Demo02 {
    public static void main(String[] args) {
        test01();
        test02();
    }

    /**
     * 基于（相对于类内存地址的）偏移量，修改字段值
     *
     * before:0
     * after:2
     *
     * 注意:修改int值，那么类A中不要使用int的包装类型Integer，不然以Object处理
     */
    public static void test01() {
        Unsafe theUnasfe = cn.jdemo.unsafe.theUnsafe.AllInOne.getTheUnasfe();
        Class<A> aClass = A.class;
        try {
            long valOffset1 = theUnasfe.staticFieldOffset(aClass.getDeclaredField("intVal1"));
            System.out.println("before:"+ A.intVal1);
            theUnasfe.putInt( A.class, valOffset1, 2);
            System.out.println("after:"+ A.intVal1);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }

    /**
     * 基于（相对于类实例内存地址的）偏移量，修改字段值
     *
     * 输出内容:
     * before:0
     * after:4
     *
     * 注意:修改int值，那么类A中不要使用int的包装类型Integer，不然以Object处理
     */
    public static void test02() {
        Unsafe theUnasfe = cn.jdemo.unsafe.theUnsafe.AllInOne.getTheUnasfe();
        A a = new A();
        Class<? extends A> aClass = a.getClass();
        try {
            long valOffset2 = theUnasfe.objectFieldOffset(aClass.getDeclaredField("intVal2"));
            System.out.println("before:"+a.intVal2);
            theUnasfe.putInt(a, valOffset2, 4);
            System.out.println("after:"+a.intVal2);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }
    static class A{
        static int intVal1=0;
        int intVal2=0;
    }
}
